package com.mycompany.inventory.controller;

import java.util.HashMap;

import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Components;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.event.DropEvent;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.select.SelectorComposer;
import org.zkoss.zk.ui.select.annotation.Wire;
import org.zkoss.zul.DefaultTreeNode;
import org.zkoss.zul.Hlayout;
import org.zkoss.zul.Image;
import org.zkoss.zul.Label;
import org.zkoss.zul.Tree;
import org.zkoss.zul.Treecell;
import org.zkoss.zul.Treeitem;
import org.zkoss.zul.TreeitemRenderer;
import org.zkoss.zul.Treerow;
import org.zkoss.zul.Window;
import org.zkoss.zul.Window.Mode;

import com.mycompany.inventory.pojo.MenuList;
import com.mycompany.inventory.pojo.Menu;
import com.mycompany.inventory.util.AdvancedTreeModel;
import com.mycompany.inventory.pojo.TreeNode;

public class MenuWindowComposer extends SelectorComposer<Component> {
	@Wire
	private Window menuWindow;
	@Wire
	private Tree tree;

	private AdvancedTreeModel menuTreeModel;

	public void doAfterCompose(Component comp) throws Exception {
		super.doAfterCompose(comp);		
		menuTreeModel = new AdvancedTreeModel(new MenuList().getRoot());
		tree.setItemRenderer(new MenuTreeRenderer());
		tree.setModel(menuTreeModel);
	}

	/**
	 * The structure of tree
	 * 
	 * <pre>
	 * &lt;treeitem>
	 *   &lt;treerow>
	 *     &lt;treecell>...&lt;/treecell>
	 *   &lt;/treerow>
	 *   &lt;treechildren>
	 *     &lt;treeitem>...&lt;/treeitem>
	 *   &lt;/treechildren>
	 * &lt;/treeitem>
	 * </pre>
	 */
	private final class MenuTreeRenderer implements TreeitemRenderer {
		@Override
		public void render(final Treeitem treeItem, Object treeNode, int index) throws Exception {
			TreeNode ctn = (TreeNode) treeNode;
			Menu menu = (Menu) ctn.getData();
			Treerow dataRow = new Treerow();
			dataRow.setParent(treeItem);
			treeItem.setValue(ctn);
			treeItem.setOpen(ctn.isOpen());

			if (!isCategory(menu)) { // Menu Row
				Hlayout hl = new Hlayout();
				hl.appendChild(new Image("/images/icons/" + menu.getProfilepic()));
				hl.appendChild(new Label(menu.getName()));
				hl.setSclass("h-inline-block");
				Treecell treeCell = new Treecell();
				treeCell.appendChild(hl);
				dataRow.setDraggable("true");
				dataRow.appendChild(treeCell);
				dataRow.addEventListener(Events.ON_CLICK, new EventListener() {
					@Override
					public void onEvent(Event event) throws Exception {
						TreeNode clickedNodeValue = (TreeNode) ((Treeitem) event.getTarget().getParent())
								.getValue();
						Component view = org.zkoss.zk.ui.Path.getComponent("/main");
						if(view !=null) Components.removeAllChildren(view);						
						HashMap<String, String> dataArgs = new HashMap<String, String>();
						dataArgs.put("name", clickedNodeValue.getData().toString());
						Menu menu = (Menu)clickedNodeValue.getData();
						try{
							if(menu.getName().equals("Vendor List")){
								Executions.createComponents("pages/vendor/main.zul", view, dataArgs);							
							}else if (menu.getName().equals("Customer List")) {
								Executions.createComponents("pages/customer/main.zul", view, dataArgs);
							}else if (menu.getName().equals("General Settings")) {
								Executions.createComponents("pages/general/main.zul", view, dataArgs);
							}else if (menu.getName().equals("Product List")) {
								Executions.createComponents("pages/product/main.zul", view, dataArgs);
							}else if (menu.getName().equals("Product Categories")) {
								Executions.createComponents("pages/category/main.zul", view, dataArgs);
							}else if (menu.getName().equals("Current Stock")) {
								Executions.createComponents("pages/stock/main.zul", view, dataArgs);							
							}else if (menu.getName().equals("New Purchase Order")) {
								Executions.createComponents("pages/purchasing/main.zul", view, dataArgs);
							}else{
								Executions.createComponents("warning.zul", view, dataArgs);
							}
						}catch (RuntimeException e) {
							// TODO: handle exception
						}
					}
				});
			} else { // Category Row
				dataRow.appendChild(new Treecell(menu.getCategory()));
			}
			// Both category row and contact row can be item dropped
			dataRow.setDroppable("true");
			dataRow.addEventListener(Events.ON_DROP, new EventListener() {
				@Override
				public void onEvent(Event event) throws Exception {
					// The dragged target is a TreeRow belongs to an
					// Treechildren of TreeItem.
					Treeitem draggedItem = (Treeitem) ((DropEvent) event).getDragged().getParent();
					TreeNode draggedValue = (TreeNode) draggedItem.getValue();
					Treeitem parentItem = treeItem.getParentItem();
					menuTreeModel.remove(draggedValue);
					if (isCategory((Menu) ((TreeNode) treeItem.getValue()).getData())) {
						menuTreeModel.add((TreeNode) treeItem.getValue(),
								new DefaultTreeNode[] { draggedValue });
					} else {
						int index = parentItem.getTreechildren().getChildren().indexOf(treeItem);
						menuTreeModel.insert(parentItem.getValue(), index, index,
								new DefaultTreeNode[] { draggedValue });
					}
				}
			});

		}

		private boolean isCategory(Menu contact) {
			return contact.getName() == null;
		}
	}
}